package tt.dz.service.imp.sys;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import tt.dz.dao.ext.system.OmsRoleAuthRepo;
import tt.dz.dao.ext.system.OmsUrlListDao;
import tt.dz.dao.ext.system.OmsUrlListRepo;
import tt.dz.entity.base.JsonCommon;
import tt.dz.entity.base.JsonForList;
import tt.dz.entity.base.OmsCommonParam;
import tt.dz.entity.exception.OmsDaoException;
import tt.dz.entity.system.OmsRoleAuthEntity;
import tt.dz.entity.system.OmsUrlList;
import tt.dz.entity.system.OmsUrlListEntity;
import tt.dz.entity.system.OmsUrlTreeVO;
import tt.dz.service.imp.base.BaseService;
import tt.dz.service.sys.UrlListService;
import tt.dz.util.OmsConstant.MsgCodeEnum;

@Service
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
public class UrlListServiceImpl extends BaseService implements UrlListService
{
	private Log log = LogFactory.getLog(UrlListServiceImpl.class);

	@Autowired
	private OmsUrlListDao urlListDaoImpl;
	@Autowired
	OmsRoleAuthRepo roleAuthRepo;
	@Autowired
	OmsUrlListRepo urlListRepo;

	@Override
	public synchronized JsonCommon<?> add(OmsUrlList url)
	{
		try
		{
			String maxId = urlListDaoImpl.findMaxId(OmsUrlList.class);
			maxId = this.genarateId(maxId, 10);
			url.setUrl_id(maxId);
			this.urlListDaoImpl.add(url);
			return this.buildSuccessJsonCommon(url);
		}
		catch (OmsDaoException e)
		{
			this.logError("url add error", e);
			return this.buildOtherJsonCommon(MsgCodeEnum.ERROR400.getMsgCode(), "system error");
		}
	}

	@Override
	public JsonCommon<?> update(OmsUrlList url)
	{
		try
		{
			this.urlListDaoImpl.update(url);
			return this.buildSuccessJsonCommon(url);
		}
		catch (OmsDaoException e)
		{
			this.logError("url update error", e);
			return this.buildOtherJsonCommon(MsgCodeEnum.ERROR400.getMsgCode(), "system error");
		}
	}

	@Override
	public JsonCommon<?> delete(String urlId)
	{
		try
		{
			this.urlListDaoImpl.deleteById(urlId, OmsUrlList.class);
			return this.buildSuccessJsonCommon("success");
		}
		catch (OmsDaoException e)
		{
			this.logError("url delete error", e);
			return this.buildOtherJsonCommon(MsgCodeEnum.ERROR400.getMsgCode(), "system error");
		}
	}

	@Override
	public JsonForList<?> findPageOrAll(OmsCommonParam param, OmsUrlList url)
	{
		try
		{
			List<OmsUrlList> lst = urlListDaoImpl.pagingFind(param, url);
			int total = 0;
			if (param.isQueryTotal())
			{
				total = urlListDaoImpl.queryTotalByObject(url);
			}
			return this.buildSuccessJsonForList(param, lst, total);
		}
		catch (Exception e)
		{
			this.logError(e.getMessage(), e);
			return this.buildError400JsonForList();
		}
	}

	@Override
	public JsonCommon<?> findById(OmsUrlList url)
	{
		try
		{
			this.urlListDaoImpl.findRecordByPK(url);
			return this.buildSuccessJsonCommon(url);
		}
		catch (Exception e)
		{
			this.logError("url delete error", e);
			return this.buildOtherJsonCommon(MsgCodeEnum.ERROR400.getMsgCode(), "system error");
		}
	}

	public JsonForList<?> findUrlListByRoleId(String roleId, String levelType, boolean isExists)
	{
		try
		{
			List<OmsUrlList> lst = urlListDaoImpl.findValidUrlListByRoleId(roleId, levelType, isExists);
			return this.buildSuccessJsonForList(lst);
		}
		catch (Exception e)
		{
			this.logError(e.getMessage(), e);
			return this.buildError400JsonForList();
		}
	}

	//查询所有url，根据该roleId是否与此url关联来做区分
	@Override
	public JsonForList<?> findUrlListByRoleId(String roleId)
	{
		try
		{
			List<OmsUrlList> lst = urlListDaoImpl.findUrlListByRoleId(roleId);
			return this.buildSuccessJsonForList(lst);
		}
		catch (Exception e)
		{
			this.logError(e.getMessage(), e);
			return this.buildError400JsonForList();
		}
	}

	@Override
	public OmsUrlTreeVO getAllUrlTree(String roleId)
	{
		return urlListDaoImpl.getAllUrls(roleId);
	}

	@Override
	public OmsUrlTreeVO getAllUrlTree()
	{
		return urlListDaoImpl.getAllUrls();
	}

	@Override
	public void assignUrlToRole(OmsUrlTreeVO rootVO, String roleId, String operId)
	{
		Date now = new Date();
		ArrayList<OmsUrlTreeVO> list = convertTree2List(rootVO);
		ArrayList<OmsRoleAuthEntity> list_ra = new ArrayList<>();
		for (OmsUrlTreeVO vo : list)
		{
			if (vo.isChecked() && !"root".equals(vo.getId()))
			{
				OmsRoleAuthEntity ra = new OmsRoleAuthEntity();
				ra.setRoleId(roleId);
				ra.setUrlId(vo.getId());
				ra.setValidFlag(1);
				ra.setCreateTime(now);
				ra.setUpdateTime(now);
				ra.setCreateOperId(operId);
				ra.setUpdateOperId(operId);
				list_ra.add(ra);
			}
		}
		roleAuthRepo.deleteByRoleId(roleId);
		roleAuthRepo.save(list_ra);
	}

	@Override
	public void updateUrls(OmsUrlTreeVO originTreeVO, OmsUrlTreeVO updatedTreeVO)
	{
		ArrayList<OmsUrlTreeVO> list_updated = convertTree2List(updatedTreeVO);
		ArrayList<OmsUrlTreeVO> list_origin = convertTree2List(originTreeVO);
		ArrayList<OmsUrlListEntity> list_updatedEntity = new ArrayList<>();
		HashMap<String, String> newIdMapping = new HashMap<>();
		Integer maxId = Integer.valueOf( urlListRepo.findMaxId());
		for (OmsUrlTreeVO vo : list_updated)
		{
			if (!"root".equals(vo.getId()))
			{
				OmsUrlListEntity entity = new OmsUrlListEntity();
				String id = vo.getId();
				if (id.startsWith("new_"))
				{
					id = newIdMapping.get(id);
					if (id == null)
					{
						id = String.format("%010d", ++maxId);
						newIdMapping.put(vo.getId(), id);
					}
				}
				entity.setUrlId(id);
				entity.setUrlName(vo.getName());
				String parent_id = vo.getParent();
				if (parent_id.startsWith("new_"))
					parent_id = newIdMapping.get(parent_id);
				entity.setPreUrlId(parent_id);
				entity.setValidFlag(1);
				entity.setUrlPath(vo.getUrl());
				entity.setIsLeaf(vo.isLeaf() ? 1 : 0);
				entity.setSortCol(vo.getOrder());
				entity.setUrlLevel(vo.getLevel());
				list_updatedEntity.add(entity);
			}
		}

		list_origin.removeAll(list_updated);
		ArrayList<OmsUrlListEntity> list_deletedEntity = new ArrayList<>();
		for(OmsUrlTreeVO vo : list_origin)
		{
			OmsUrlListEntity entity = new OmsUrlListEntity();
			entity.setUrlId(vo.getId());
			list_deletedEntity.add(entity);
		}

		for(OmsUrlListEntity e : list_updatedEntity )
			log.info(e.getUrlId());

		log.info("-------------");
		for(OmsUrlListEntity e : list_deletedEntity )
			log.info(e.getUrlId());
		urlListRepo.delete(list_deletedEntity);
		urlListRepo.save(list_updatedEntity);
	}

	private ArrayList<OmsUrlTreeVO> convertTree2List(OmsUrlTreeVO tree)
	{
		ArrayList<OmsUrlTreeVO> list = new ArrayList<>();
		list.add(tree);
		if (tree.getSubTree() != null && !tree.getSubTree().isEmpty())
		{
			for (OmsUrlTreeVO child : tree.getSubTree())
				list.addAll(convertTree2List(child));
		}

		return list;
	}

}
